package com.cmcc.xdr.util;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Date;

import com.google.common.hash.HashCode;

public class BufferLoadUtil {
	/**
	 * 从buff中读取指定长度的数据,buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static byte[] loadByte(ByteBuffer buffer,int length) {
		byte[] temp = new byte[length];
		buffer.get(temp);
		return temp;
	}

	/**
	 * @comment 从buff中读取指定长度的数据被将其转换为ip地址。ipv4仅占用四个字节所以将多余的截去。
	 * 
	 * @param length
	 * @return
	 */
	public static String loadIp(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return "";
		};
		return JudgeBytes.toIpAddress(b);
	}

	

	/**
	 * 从buff中读取指定长度的数据并转换为BigInteger
	 * 
	 * @param length
	 * @return
	 */
	public static BigInteger loadBigInteger(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return new BigInteger("0");
		};
		return JudgeBytes.toBigInteger(b);
	}

	
	/**
	 * 从buff中读取指定长度的数据并转换为long buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static  long loadLong(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return 0;
		};
		return JudgeBytes.toBigInteger(b).longValue();

	}

	/**
	 * 从buff中读取指定长度的数据并转换为int buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static int loadInt(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return 0;
		};
		int val = JudgeBytes.toBigInteger(b).intValue();
		if(val > 2147483648l || val < 0){//如果大于int的最大值则存0
			return 0;
		}
		return val;
//		return MessageUtil.toBigInteger(loadByte(length)).intValue();
	}
	
	/**
	 * 从buff中读取指定长度的数据并转换为int buffer的pos会改变所以需要按顺序读取
	 * 读取SequenceId 专用
	 * @param length
	 * @return
	 */
	public static int loadSequenceId(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return 0;
		};
		int val = JudgeBytes.toBigInteger(b).intValue();
		return val;
	}
	
	/**
	 * 从buff中读取指定长度的数据并转换为int buffer的pos会改变所以需要按顺序读取,返回的是字符串
	 * 
	 * @param length
	 * @return
	 */
	public static String loadStrInt(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return "";
		};
		return JudgeBytes.toBigInteger(b).intValue()+"";
	}
	
	public static String loadStrLong(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return "";
		};
		return JudgeBytes.toBigInteger(b).longValue() + "";

	}
	
	public static String loadStrLongstr(ByteBuffer buffer,int length) {//数据库里存的是int
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"0";
			return "0";
		};
		long val = JudgeBytes.toBigInteger(b).longValue();
		if(val > 2147483648l){//如果大于int的最大值则存0
			return "0";
		}
		return val + "";

	}
	
	/**
	 * 从buff中读取指定长度的数据并转换为int buffer的pos会改变所以需要按顺序读取，如果参数带有0，默认值则返回-1
	 * 
	 * @param length
	 * @return
	 */
	public static int loadInt2(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取-1;
			return -1;
		};
		return JudgeBytes.toBigInteger(b).intValue();
//		return MessageUtil.toBigInteger(loadByte(length)).intValue();
	}

	/**
	 * 从buff中读取指定长度的数据并转换为string buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static String loadStr(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return "";
		};
		for (int i = 0; i < b.length; i++) {
			byte temp = b[i];
			if(temp == -1){//如果是F补位则总长度减1
				length --;
			}
		}
		if(b.length > length){//如果长度有减则是由F补位，则重新定一个byte[]然后解析成字符串，防止乱码
			byte[] bytelast = new byte[length];
			bytelast = subBytes(b,0,length);
			return new String(bytelast);
		}
		return new String(b);
//		return new String(loadByte(length));

	}

	 /**
	  * 从一个byte[]数组中截取一部分
	  * @param src
	  * @param begin
	  * @param count
	  * @return
	  */
	 public static byte[] subBytes(byte[] src, int begin, int count) {
	     byte[] bs = new byte[count];
	     for (int i=begin; i<begin+count; i++) bs[i-begin] = src[i];
	     return bs;
	 }
	

	/**
	 * 从buff中读取指定长度的数据并转换为16进制Hash str, buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static String loadHexStr(ByteBuffer buffer,int length) {
		byte[] b = loadByte(buffer,length);
		if(JudgeBytes.judgeBytesIfFdefault(b, length)){//如果這個值等於length个F，则是默认值，取"";
			return "";
		};
		return HashCode.fromBytes(b).toString();
	}
	
	/**
	 * 根据byte数据并转换为16进制Hash str
	 * 
	 * @param length
	 * @return
	 */
	public static String loadHexStrByByte(byte[] byteData) {
		return HashCode.fromBytes(byteData).toString();
	}


	// TODO load(data,length)系方法存在参数传递问题
	// Note that java.lang.Integer is immutable.
	// try using org.apache.commons.lang.mutable.MutableInt from Apache Commons
	// library.

	/**
	 * 从buff中读取指定长度的数据,buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static byte[] load(ByteBuffer buffer,byte[] data, int length) {
		data = loadByte(buffer,length);
		return data;
	}

	/**
	 * 从buff中读取指定长度的数据并转换为long.buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static Long load(ByteBuffer buffer,Long data, int length) {
		data = loadBigInteger(buffer,length).longValue();
		return data;
	}

	/**
	 * 从buff中读取指定长度的数据并转换为Date.buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static Date load(ByteBuffer buffer,Date data, int length) {
		long milliseconds = loadBigInteger(buffer,length).longValue();
		data = new Date(milliseconds);
		return data;
	}

	/**
	 * 从buff中读取指定长度的数据并转换为int.buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static int load(ByteBuffer buffer,Integer data, int length) {
		data = loadBigInteger(buffer,length).intValue();
		return data;
	}
	
	/**
	 * 将byte解析为int
	 * 原 load方法经过byte直接解析成数字int
	 * @param length
	 * @return
	 */
	public static int loadIntByByte(Integer data, byte[] byteData) {
		data = JudgeBytes.toBigInteger(byteData).intValue();
		return data;
	}

	/**
	 * 从buff中读取指定长度的数据并转换为string buffer的pos会改变所以需要按顺序读取
	 * 
	 * @param length
	 * @return
	 */
	public static String load(ByteBuffer buffer,String data, int length) {
		data = new String(loadByte(buffer,length));
		return data;

	}

	public static Double load(ByteBuffer buffer,Double data, int length) {
		byte[] temp = loadByte(buffer,length);
		data = JudgeBytes.toDouble(temp);
		return data;
	}
}
